<?php
	namespace app\controller\api;
    use think\facade\Request as RequestFacade;
    use think\facade\Db;
    use think\Model;
    use think\Request;
//    JWT加密uid 和过期时间
    use Firebase\JWT\JWT;
    use Firebase\JWT\Key;
    use think\facade\Config;

    class User extends  Model
	{
        protected $name = 'users';
//        查询隐藏字段
        protected $hidden = [
            'openid',
        ];

//        jwt加密 openid字段
        private function generateToken($openid): array
        {
            $key = Config::get('jwt.secret'); // 你的密钥
            $expires_time = time() + Config::get('jwt.expires_time'); // 过期时间
            $payload = [
                'user_id' => $openid,
                'exp' => $expires_time
            ];
            $algorithm = 'HS256'; // 哈希算法
            $keyId = "keyId";
            $token = JWT::encode($payload, $key, $algorithm,$keyId);
            return array(
                'token' => $token,
                'expires_time' => $expires_time
            );
        }

//      登陆和注册都使用该方法
        public function login($code,$appid){
            $openid_info = $this->get_openid($code,$appid);
            if($openid_info['code'] != 0){
                return fail($openid_info);
            }
            $openid = $openid_info['openid'];
            $appid = $openid_info['appid'];
            $appname = $openid_info['appname'];

            $clickid = RequestFacade::param('clickid');

            $res = Db::name('users')->where('openid',$openid)->find();

            if($res == null){ //没有该用户信息进行注册
//                return success('注册');
                $now_time = time();
                $data['appid'] = $appid;
                $data['appname'] = $appname;
                $data['openid'] = $openid;
                $data['register_date'] = $now_time;
                $data['register_date_str'] = date('Y-m-d H:i:s', $now_time);
                $data['last_login_date'] = date('Y-m-d H:i:s');
                $token_info = $this->generateToken($openid);
                $data['token'] = $token_info['token'];
                $data['expires_time'] = $token_info['expires_time'];
//                存入字段
                $Db_action = $this->save($data);

                $user_info = $this->get_user_data($openid);

                if($Db_action){
                    return success($user_info,'200','注册成功');
                }else{
                    return fail($user_info,-1,'注册失败');
                }
            }else{ //有 进行登陆
                $user_info = $this->get_user_data($openid);
                $user_info->last_login_date = date('Y-m-d H:i:s'); // 更新最后登录时间

                $jwt_user_info = $this->verification_token_expires($user_info->token);
//                如果token已过期 重新生成token
                if($jwt_user_info['code'] == -1){
                    $token_info = $this->generateToken($openid);
                    $user_info->token = $token_info['token'];
                    $user_info->expires_time = $token_info['expires_time'];
                }else{
//                    返回上次 登录的过期时间
                    $user_info->expires_time = $jwt_user_info['expires_time'];
                }

                $user_info->save(); // 保存更改
                return success($user_info);
            }
        }

//        验证token是否过期
        private static function verification_token_expires($token){
            try {
                $key = Config::get('jwt.secret'); // 你的密钥
                $keys = new Key($key, 'HS256');
                // 解码 Token，自动验证签名和过期时间
                $decoded = JWT::decode($token, $keys);

                // Token 有效，继续处理请求
                // $decoded 中包含了 Token 的信息
                // 例如 $decoded->email 获取用户的邮箱信息
                return array(
                    "code" => 0,
                    "expires_time" => $decoded->exp
                );
            } catch (\Exception $e) {
                // Token 无效或已过期
                // 返回错误信息给前端，比如 401 Unauthorized
               return array(
                   "code" => -1
               );
            }
        }

        private function get_user_data($openid){
            return $this->where('openid',$openid)->find();
        }

        public function get_openid($code,$appid){
            $res = Db::name('appid')->where( "appid",$appid)->field('appsecret,appname')->find();

            $appsecret = $res['appsecret'];
            $appname = $res['appname'];

            $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$appsecret}&js_code={$code}&grant_type=authorization_code";

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
            curl_setopt($ch, CURLOPT_URL,$url);
            //为了支持cookie
            curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//            curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //请求参数
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $result = array();
            $result = curl_exec($ch);
            $result = json_decode($result,true);
            if(array_key_exists('errcode',$result)){
                return array(
                    "code" => "40001",
                    "msg" => "code已过期"
                );
            }else{
               return array(
                    "code" => "0",
                    "msg" => '获取成功',
                    "appid" => $appid,
                    "appname" => $appname,
                    "openid" => $result['openid'],
                );
            }

        }

	    public function get_user_info(Request $request)
	    {
            $openid = $request->openid;
            $res = $this->where('openid',$openid)->find();
            return success($res);
	    }
	}